package com.ruoyi.business.service.impl;

import java.math.BigDecimal;
import java.sql.Time;
import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.business.domain.dto.TrainStationGroupDTO;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.TrainStationMapper;
import com.ruoyi.business.domain.TrainStation;
import com.ruoyi.business.service.ITrainStationService;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.ss.usermodel.IndexedColors;
import com.ruoyi.business.domain.vo.TrainStationVo;

/**
 * 火车车站Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-03-06
 */
@Service
public class TrainStationServiceImpl implements ITrainStationService 
{
    @Autowired
    private TrainStationMapper trainStationMapper;

    /**
     * 查询火车车站
     * 
     * @param id 火车车站主键
     * @return 火车车站
     */
    @Override
    public TrainStation selectTrainStationById(Long id)
    {
        return trainStationMapper.selectTrainStationById(id);
    }

    /**
     * 查询火车车站列表
     * 
     * @param trainStation 火车车站
     * @return 火车车站
     */
    @Override
    public List<TrainStation> selectTrainStationList(TrainStation trainStation)
    {
        return trainStationMapper.selectTrainStationList(trainStation);
    }

    /**
     * 新增火车车站
     * 
     * @param trainStation 火车车站
     * @return 结果
     */
    @Override
    public int insertTrainStation(TrainStation trainStation)
    {
        trainStation.setCreateTime(DateUtils.getNowDate());
        return trainStationMapper.insertTrainStation(trainStation);
    }

    /**
     * 修改火车车站
     * 
     * @param trainStation 火车车站
     * @return 结果
     */
    @Override
    public int updateTrainStation(TrainStation trainStation)
    {
        trainStation.setUpdateTime(DateUtils.getNowDate());
        return trainStationMapper.updateTrainStation(trainStation);
    }

    /**
     * 批量删除火车车站
     * 
     * @param ids 需要删除的火车车站主键
     * @return 结果
     */
    @Override
    public int deleteTrainStationByIds(Long[] ids)
    {
        return trainStationMapper.deleteTrainStationByIds(ids);
    }

    /**
     * 删除火车车站信息
     * 
     * @param id 火车车站主键
     * @return 结果
     */
    @Override
    public int deleteTrainStationById(Long id)
    {
        return trainStationMapper.deleteTrainStationById(id);
    }

    /**
     * 批量新增火车车站
     * @param trainStationList
     * @return 结果
     */
    @Override
    public int InsertTrainStations(List<TrainStation> trainStationList) {
        return trainStationMapper.InsertTrainStations(trainStationList);
    }

    /**
     * 按车次编号分组查询火车车站（支持分页）
     *
     * @param trainStation 查询参数
     * @return 分页后的火车车站分组列表
     */
    @Override
    public Map<String, Object> selectTrainStationGroups(TrainStation trainStation) {
        Map<String, Object> result = new HashMap<>();

        // 1. 首先查询符合条件的所有不同车次编号（不带分页）
        int pageNum = trainStation.getPageNum();
        int pageSize = trainStation.getPageSize();

        // 暂时清除分页参数，查询所有匹配的车次编号
        trainStation.setPageNum(0);
        trainStation.setPageSize(0);

        // 查询所有不同的车次编号
        List<String> allTrainCodes = trainStationMapper.selectDistinctTrainCodes(trainStation);

        // 计算总车次数（用于前端分页）
        int totalTrainCodes = allTrainCodes.size();
        result.put("total", totalTrainCodes);

        // 没有数据时直接返回
        if (totalTrainCodes == 0) {
            result.put("groups", new ArrayList<>());
            return result;
        }

        // 2. 计算分页范围
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, totalTrainCodes);

        // 3. 创建新列表存储当前页车次编号 - 不使用subList避免反射问题
        List<String> pageTrainCodes = new ArrayList<>();
        // 防止索引越界
        if (startIndex < totalTrainCodes) {
            for (int i = startIndex; i < endIndex; i++) {
                pageTrainCodes.add(allTrainCodes.get(i));
            }
        }

        // 4. 只查询当前页包含的车次的站点数据
        List<TrainStationGroupDTO> groupResults = new ArrayList<>();

        if (!pageTrainCodes.isEmpty()) {
            // 查询当前页所有车次的站点数据
            TrainStation queryParam = new TrainStation();
            queryParam.setParams(trainStation.getParams()); // 保留原始查询参数
            queryParam.setTrainCodes(pageTrainCodes); // 设置当前页的车次编号列表

            // 查询站点数据
            List<TrainStation> trainStations = trainStationMapper.selectTrainStationsByTrainCodes(queryParam);

            // 按车次编号分组
            Map<String, List<TrainStation>> groups = trainStations.stream()
                    .collect(Collectors.groupingBy(TrainStation::getTrainCode));

            // 处理每个分组
            groupResults = pageTrainCodes.stream().map(trainCode -> {
                List<TrainStation> stations = groups.getOrDefault(trainCode, new ArrayList<>());

                // 按站序排序
                stations.sort(Comparator.comparing(TrainStation::getIndex));

                TrainStationGroupDTO groupDTO = new TrainStationGroupDTO();
                groupDTO.setTrainCode(trainCode);
                groupDTO.setStations(stations);

                // 获取第一站和最后一站
                if (!stations.isEmpty()) {
                    groupDTO.setFirstStation(stations.get(0).getName());
                    groupDTO.setLastStation(stations.get(stations.size() - 1).getName());

                    // 计算总里程
                    BigDecimal totalKm = BigDecimal.ZERO;
                    for (TrainStation station : stations) {
                        if (station.getKm() != null) {
                            totalKm = totalKm.add(station.getKm());
                        }
                    }
                    groupDTO.setTotalKm(totalKm);

                    // 计算行程时长 - 使用终点站出站时间减去起点站进站时间
                    if (stations.size() > 1) {
                        // 获取第一站的进站时间和最后一站的信息
                        TrainStation firstStation = stations.get(0);
                        TrainStation lastStation = stations.get(stations.size() - 1);
                        
                        Time firstInTime = firstStation.getInTime();
                        Time lastOutTime = lastStation.getOutTime();
                        
                        // 记录调试信息
                        System.out.println("车次[" + trainCode + "]行程时间计算：");
                        System.out.println("  - 起点站: " + firstStation.getName() + ", 进站时间: " + firstInTime);
                        System.out.println("  - 终点站: " + lastStation.getName() + ", 出站时间: " + lastOutTime);
                        
                        // 特殊处理：如果终点站出站时间为00:00:00（终点站标记）
                        if (lastOutTime != null && lastOutTime.toString().equals("00:00:00")) {
                            System.out.println("  - 检测到终点站出站时间为00:00:00，使用最后一站的进站时间代替");
                            
                            // 使用终点站的进站时间替代出站时间进行计算
                            Time lastInTime = lastStation.getInTime();
                            System.out.println("  - 终点站进站时间: " + lastInTime);
                            
                            if (firstInTime != null && lastInTime != null) {
                                // 计算时间差（毫秒）
                                long diffMillis = lastInTime.getTime() - firstInTime.getTime();
                                if (diffMillis < 0) {
                                    // 如果是跨天，加上24小时
                                    diffMillis += 24 * 60 * 60 * 1000;
                                    System.out.println("  - 检测到跨天情况，已添加24小时");
                                }
                                
                                // 转换为时:分:秒格式
                                long hours = diffMillis / (60 * 60 * 1000);
                                long minutes = (diffMillis % (60 * 60 * 1000)) / (60 * 1000);
                                long seconds = (diffMillis % (60 * 1000)) / 1000;
                                
                                String totalTimeStr = String.format("%02d:%02d:%02d", hours, minutes, seconds);
                                groupDTO.setTotalTime(totalTimeStr);
                                
                                System.out.println("  - 计算结果：时间差(毫秒): " + diffMillis + ", 行程时长: " + totalTimeStr);
                            } else {
                                System.out.println("  - 警告：起点站进站时间或终点站进站时间为空，无法计算行程时长");
                            }
                        } 
                        // 正常情况：终点站出站时间正常
                        else if (firstInTime != null && lastOutTime != null) {
                            // 计算时间差（毫秒）
                            long diffMillis = lastOutTime.getTime() - firstInTime.getTime();
                            if (diffMillis < 0) {
                                // 如果是跨天，加上24小时
                                diffMillis += 24 * 60 * 60 * 1000;
                                System.out.println("  - 检测到跨天情况，已添加24小时");
                            }

                            // 转换为时:分:秒格式
                            long hours = diffMillis / (60 * 60 * 1000);
                            long minutes = (diffMillis % (60 * 60 * 1000)) / (60 * 1000);
                            long seconds = (diffMillis % (60 * 1000)) / 1000;

                            String totalTimeStr = String.format("%02d:%02d:%02d", hours, minutes, seconds);
                            groupDTO.setTotalTime(totalTimeStr);
                            
                            System.out.println("  - 计算结果：时间差(毫秒): " + diffMillis + ", 行程时长: " + totalTimeStr);
                        } else {
                            System.out.println("  - 警告：起点站进站时间或终点站出站时间为空，无法计算行程时长");
                        }
                    }
                }

                return groupDTO;
            }).collect(Collectors.toList());
        }

        result.put("groups", groupResults);
        return result;
    }

    /**
     * 下载火车车站导入模板 - 不包含错误字段
     */
    @Override
    public void downloadCustomTemplate(HttpServletResponse response) throws IOException {
        // 创建自定义的工作簿和工作表
        SXSSFWorkbook wb = new SXSSFWorkbook(500);
        try {
            Sheet sheet = wb.createSheet("火车车站数据");
            
            // 创建表头行并设置样式
            Row headerRow = sheet.createRow(0);
            CellStyle headerStyle = wb.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            
            Font headerFont = wb.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            
            // 设置含ID的标题行
            String[] headers = {"ID", "车次编号", "站序", "站名", "站名拼音", "进站时间", "出站时间", "停站时长", "里程"};
            for (int i = 0; i < headers.length; i++) {
                Cell headerCell = headerRow.createCell(i);
                headerCell.setCellValue(headers[i]);
                headerCell.setCellStyle(headerStyle);
                sheet.setColumnWidth(i, 5000); // 设置合适的列宽
            }
            
            // 创建数据行样式
            CellStyle dataStyle = wb.createCellStyle();
            dataStyle.setBorderBottom(BorderStyle.THIN);
            dataStyle.setBorderLeft(BorderStyle.THIN);
            dataStyle.setBorderRight(BorderStyle.THIN);
            dataStyle.setBorderTop(BorderStyle.THIN);
            dataStyle.setAlignment(HorizontalAlignment.CENTER); // 居中对齐
            
            // 添加示例数据 - 北京西站
            Row exampleRow1 = sheet.createRow(1);
            
            // ID示例
            Cell cell00 = exampleRow1.createCell(0);
            cell00.setCellValue("1577098763758821376");
            cell00.setCellStyle(dataStyle);
            
            // 车次编号示例
            Cell cell01 = exampleRow1.createCell(1);
            cell01.setCellValue("G1234");
            cell01.setCellStyle(dataStyle);
            
            // 站序示例
            Cell cell02 = exampleRow1.createCell(2);
            cell02.setCellValue("0");
            cell02.setCellStyle(dataStyle);
            
            // 站名示例
            Cell cell03 = exampleRow1.createCell(3);
            cell03.setCellValue("北京西站");
            cell03.setCellStyle(dataStyle);
            
            // 站名拼音示例
            Cell cell04 = exampleRow1.createCell(4);
            cell04.setCellValue("beijingxizhan");
            cell04.setCellStyle(dataStyle);
            
            // 进站时间示例
            Cell cell05 = exampleRow1.createCell(5);
            cell05.setCellValue("08:00:00");
            cell05.setCellStyle(dataStyle);
            
            // 出站时间示例
            Cell cell06 = exampleRow1.createCell(6);
            cell06.setCellValue("08:05:00");
            cell06.setCellStyle(dataStyle);
            
            // 停站时长示例
            Cell cell07 = exampleRow1.createCell(7);
            cell07.setCellValue("00:05:00");
            cell07.setCellStyle(dataStyle);
            
            // 里程示例
            Cell cell08 = exampleRow1.createCell(8);
            cell08.setCellValue("0");
            cell08.setCellStyle(dataStyle);
            
            // 添加示例数据 - 天津南站
            Row exampleRow2 = sheet.createRow(2);
            
            // ID示例
            Cell cell10 = exampleRow2.createCell(0);
            cell10.setCellValue("1577098763758821377");
            cell10.setCellStyle(dataStyle);
            
            // 车次编号示例
            Cell cell11 = exampleRow2.createCell(1);
            cell11.setCellValue("G1234");
            cell11.setCellStyle(dataStyle);
            
            // 站序示例
            Cell cell12 = exampleRow2.createCell(2);
            cell12.setCellValue("1");
            cell12.setCellStyle(dataStyle);
            
            // 站名示例
            Cell cell13 = exampleRow2.createCell(3);
            cell13.setCellValue("天津南站");
            cell13.setCellStyle(dataStyle);
            
            // 站名拼音示例
            Cell cell14 = exampleRow2.createCell(4);
            cell14.setCellValue("tianjinnanzhan");
            cell14.setCellStyle(dataStyle);
            
            // 进站时间示例
            Cell cell15 = exampleRow2.createCell(5);
            cell15.setCellValue("08:45:00");
            cell15.setCellStyle(dataStyle);
            
            // 出站时间示例
            Cell cell16 = exampleRow2.createCell(6);
            cell16.setCellValue("08:48:00");
            cell16.setCellStyle(dataStyle);
            
            // 停站时长示例
            Cell cell17 = exampleRow2.createCell(7);
            cell17.setCellValue("00:03:00");
            cell17.setCellStyle(dataStyle);
            
            // 里程示例
            Cell cell18 = exampleRow2.createCell(8);
            cell18.setCellValue("150");
            cell18.setCellStyle(dataStyle);
            
            // 添加数据验证规则说明
            Row noteRow = sheet.createRow(4);
            Cell noteCell = noteRow.createCell(0);
            noteCell.setCellValue("数据验证规则:");
            CellStyle noteStyle = wb.createCellStyle();
            Font noteFont = wb.createFont();
            noteFont.setBold(true);
            noteStyle.setFont(noteFont);
            noteCell.setCellStyle(noteStyle);
            
            // 添加验证规则
            String[] rules = {
                "• 车次编号必须已存在于列车管理中",
                "• 同一车次内，站序不能重复",
                "• 同一车次内，站名不能重复",
                "• 站点时间不能冲突，出站时间必须小于进站时间",
                "• 第一站（站序为0）的里程必须为0"
            };
            
            for (int i = 0; i < rules.length; i++) {
                Row ruleRow = sheet.createRow(5 + i);
                Cell ruleCell = ruleRow.createCell(0);
                ruleCell.setCellValue(rules[i]);
                // 合并单元格使规则跨越多列
                sheet.addMergedRegion(new CellRangeAddress(5 + i, 5 + i, 0, 8));
            }
            
            // 输出到响应
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "train_station_template.xlsx";
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            
            wb.write(response.getOutputStream());
        } finally {
            wb.dispose();
        }
    }

    /**
     * 导出火车车站导入错误数据 - 使用ID替代行号
     */
    @Override
    public void exportCustomErrorData(HttpServletResponse response, List<TrainStationVo> errorDataList) throws IOException {
        // 创建自定义的工作簿和工作表
        SXSSFWorkbook wb = new SXSSFWorkbook(500);
        try {
            Sheet sheet = wb.createSheet("火车车站错误数据");
            
            // 创建表头行并设置样式
            Row headerRow = sheet.createRow(0);
            CellStyle headerStyle = wb.createCellStyle();
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            
            Font headerFont = wb.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            
            // 设置列，包含ID而不是行号
            String[] headers = {"ID", "车次编号", "站序", "站名", "站名拼音", "进站时间", "出站时间", "停站时长", "里程", "错误原因"};
            for (int i = 0; i < headers.length; i++) {
                Cell headerCell = headerRow.createCell(i);
                headerCell.setCellValue(headers[i]);
                headerCell.setCellStyle(headerStyle);
                sheet.setColumnWidth(i, 6000); // 设置合适的列宽
            }
            
            // 创建数据行样式
            CellStyle dataStyle = wb.createCellStyle();
            dataStyle.setBorderBottom(BorderStyle.THIN);
            dataStyle.setBorderLeft(BorderStyle.THIN);
            dataStyle.setBorderRight(BorderStyle.THIN);
            dataStyle.setBorderTop(BorderStyle.THIN);
            
            // 错误信息样式（红色文字）
            CellStyle errorStyle = wb.createCellStyle();
            errorStyle.cloneStyleFrom(dataStyle);
            Font errorFont = wb.createFont();
            errorFont.setColor(IndexedColors.RED.getIndex());
            errorStyle.setFont(errorFont);
            
            // 如果没有数据，添加一条提示
            if (errorDataList == null || errorDataList.isEmpty()) {
                Row dataRow = sheet.createRow(1);
                Cell cell = dataRow.createCell(0);
                cell.setCellValue("没有错误数据");
                cell.setCellStyle(dataStyle);
                sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 9));
            } else {
                // 填充数据行
                int rowIndex = 1;
                for (TrainStationVo vo : errorDataList) {
                    Row dataRow = sheet.createRow(rowIndex++);
                    
                    // ID列
                    Cell cell0 = dataRow.createCell(0);
                    String idValue = vo.getId() != null ? vo.getId().toString() : "";
                    cell0.setCellValue(idValue);
                    cell0.setCellStyle(dataStyle);
                    
                    // 车次编号
                    Cell cell1 = dataRow.createCell(1);
                    cell1.setCellValue(vo.getTrainCode() != null ? vo.getTrainCode() : "");
                    cell1.setCellStyle(dataStyle);
                    
                    // 站序
                    Cell cell2 = dataRow.createCell(2);
                    String indexValue = vo.getIndex() != null ? vo.getIndex().toString() : "";
                    cell2.setCellValue(indexValue);
                    cell2.setCellStyle(dataStyle);
                    
                    // 站名
                    Cell cell3 = dataRow.createCell(3);
                    cell3.setCellValue(vo.getName() != null ? vo.getName() : "");
                    cell3.setCellStyle(dataStyle);
                    
                    // 站名拼音
                    Cell cell4 = dataRow.createCell(4);
                    cell4.setCellValue(vo.getNamePinyin() != null ? vo.getNamePinyin() : "");
                    cell4.setCellStyle(dataStyle);
                    
                    // 进站时间
                    Cell cell5 = dataRow.createCell(5);
                    cell5.setCellValue(vo.getInTime() != null ? vo.getInTime() : "");
                    cell5.setCellStyle(dataStyle);
                    
                    // 出站时间
                    Cell cell6 = dataRow.createCell(6);
                    cell6.setCellValue(vo.getOutTime() != null ? vo.getOutTime() : "");
                    cell6.setCellStyle(dataStyle);
                    
                    // 停站时长
                    Cell cell7 = dataRow.createCell(7);
                    cell7.setCellValue(vo.getStopTime() != null ? vo.getStopTime() : "");
                    cell7.setCellStyle(dataStyle);
                    
                    // 里程
                    Cell cell8 = dataRow.createCell(8);
                    String kmValue = vo.getKm() != null ? vo.getKm() : "";
                    cell8.setCellValue(kmValue);
                    cell8.setCellStyle(dataStyle);
                    
                    // 错误原因
                    Cell cell9 = dataRow.createCell(9);
                    cell9.setCellValue(vo.getErrorMsg() != null ? vo.getErrorMsg() : "");
                    cell9.setCellStyle(errorStyle); // 使用错误样式
                }
            }
            
            // 输出到响应
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "火车车站导入错误数据_" + System.currentTimeMillis() + ".xlsx";
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            
            wb.write(response.getOutputStream());
        } finally {
            wb.dispose();
        }
    }

    /**
     * 清空火车站点数据
     * 
     * @return 结果
     */
    @Override
    public int clearTrainStation() {
        return trainStationMapper.clearTrainStation();
    }
}
